#include "AppSetting.hxx"
#include "tinystr.h"
#include "tinyxml.h"

AppSetting appSetting;
HostInfo __gHostInfo[3];

AppSetting::AppSetting(void)
{
}

void AppSetting::load(const char* pFilename)
{
	TiXmlDocument doc(pFilename);
	if (!doc.LoadFile()) return;

	TiXmlHandle hDoc(&doc);
	TiXmlElement* pElem;
	TiXmlHandle hRoot(0);

	// block: name
	{
		pElem=hDoc.FirstChildElement().Element();
		// should always have a valid root but handle gracefully if it does

		if (!pElem) return;
		m_Appname = pElem->Attribute("name");
		printf("projectName:%s\n",m_Appname.c_str());

		// save this for later
		hRoot=TiXmlHandle(pElem);
	}

	// block: DataSource
	{
		pElem=hRoot.FirstChild( "DataSource" ).Element();
		printf("%s:\n",pElem->Value());
		if (pElem)
		{
			const char *dataType = pElem->Attribute("DataType");
			if (dataType)
			{
				string data = dataType;

				if (strcmp(data.c_str(),"CAP_DATA") == 0)
					m_SourceDataType = CAP_DATA;
				else if (strcmp(data.c_str(),"MP4_DATA") == 0)
					m_SourceDataType = MP4_DATA;
				else if (strcmp(data.c_str(),"YUV_DATA") == 0)
					m_SourceDataType = YUV_DATA;
				else 
					printf("XML DataType error!");
				
				printf("DataType:%s\n",data.c_str());
			}
			
		}
	}

	//block:HostSetting
	if (m_SourceDataType == CAP_DATA)
	{
		{
			pElem = hRoot.FirstChild("DataSource").FirstChild("HostSetting").Element();
			printf("%s:\n",pElem->Value());
			const char *SaveDataType = pElem->Attribute("SaveDataType");
			if (SaveDataType) 
			{
				string data = SaveDataType;
				if (strcmp(data.c_str(),"NONE") == 0)
					m_SaveDataType = NONE;
				else if (strcmp(data.c_str(),"MP4") == 0)
					m_SaveDataType = MP4;
				else if (strcmp(data.c_str(),"YUV") == 0)
					m_SaveDataType = YUV;
				else 
					printf("XML SaveDataType error!");
				printf("SaveDataType:%s\n",data.c_str());
			}	
		}

		//block:Host
		{
			pElem = hRoot.FirstChild("DataSource").FirstChild("HostSetting").FirstChildElement().Element();
			printf("%s:\n",pElem->Value());
			for( pElem; pElem; pElem=pElem->NextSiblingElement())
			{
				int id;
				int port;
				HostSettings Hsetting;
				pElem->QueryIntAttribute("id",&id);
				pElem->QueryIntAttribute("port",&port);
				const char *pIpaddr = pElem->Attribute("ipaddr");
				const char *pUser = pElem->Attribute("user");
				const char *pPasswd = pElem->Attribute("passwd");
				const char *pParamFile = pElem->Attribute("paramfile");
				const char *pSaveFile = pElem->Attribute("savefile");
				if (pIpaddr && pUser && pPasswd && pParamFile)
					Hsetting.setHostSettings(id,port,pIpaddr,pUser,pPasswd,pParamFile,pSaveFile);
				printf("id:%d ipaddr:%s port:%d user:%s passwd:%d paramfile:%s savefile:%s\n",
					id,pIpaddr,port,pUser,pPasswd,pParamFile,pSaveFile);
				m_HostSettings.push_back(Hsetting);						
			}
		}
	}

	// block: Mp4Setting
	if(m_SourceDataType == MP4_DATA)
	{
		pElem = hRoot.FirstChild("DataSource").FirstChild("Mp4Setting").FirstChildElement().Element();
		printf("%s:\n",pElem->Value());
		for( pElem; pElem; pElem=pElem->NextSiblingElement())
		{
			int id;
			Mp4Settings Msetting;
			pElem->QueryIntAttribute("id",&id);
			const char *pSourcefile = pElem->Attribute("sourcefile");
			const char *pParamfile = pElem->Attribute("paramfile");
			if (pSourcefile && pParamfile)	
				Msetting.setMp4Settings(id,pSourcefile,pParamfile);
			printf("id:%d sourcefile:%s paramfile:%s\n",
				id,pSourcefile,pParamfile);
			m_Mp4Settings.push_back(Msetting);
		}
	}

	// block: YUVSetting
	if(m_SourceDataType == YUV_DATA)
	{
		pElem = hRoot.FirstChild("DataSource").FirstChild("YUVSetting").FirstChildElement().Element();
		printf("%s:\n",pElem->Value());
		for( pElem; pElem; pElem=pElem->NextSiblingElement())
		{
			int id;
			YUVSettings Ysetting;
			pElem->QueryIntAttribute("id",&id);
			const char *pSourcefile = pElem->Attribute("sourcefile");
			const char *pParamfile = pElem->Attribute("paramfile");
			if (pSourcefile && pParamfile)	
				Ysetting.setYUVSettings(id,pSourcefile,pParamfile);
			printf("id:%d sourcefile:%s paramfile:%s\n",
				id,pSourcefile,pParamfile);
			m_YUVSettings.push_back(Ysetting);
		}
	}

	// block: BoxCalibration
	{
		pElem = hRoot.FirstChild("BoxCalibration").FirstChild().Element();
		printf("%s:\n",pElem->Value());
		for( pElem; pElem; pElem=pElem->NextSiblingElement())
		{
			int id;
			BoxCalibrationSettings Bsetting;
			pElem->QueryIntAttribute("id",&id);
			const char *pSurface = pElem->GetText();
			if (pSurface)
			{
				printf("%s\n",pSurface);
				Bsetting.ChannelId = id;
				sscanf_s(pSurface,"%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
					&Bsetting.frontPoint[0],&Bsetting.frontPoint[1],&Bsetting.frontPoint[2],&Bsetting.frontPoint[3],
					&Bsetting.frontPoint[4],&Bsetting.frontPoint[5],&Bsetting.frontPoint[6],&Bsetting.frontPoint[7],
					&Bsetting.backPoint[0],&Bsetting.backPoint[1],&Bsetting.backPoint[2],&Bsetting.backPoint[3],
					&Bsetting.backPoint[4],&Bsetting.backPoint[5],&Bsetting.backPoint[6],&Bsetting.backPoint[7]);
				m_BoxCalibSetting.push_back(Bsetting);
			}
			
		}
	}

}

void AppSetting::save(const char* pFilename)
{
	TiXmlDocument doc;
	TiXmlElement* pElem;
	TiXmlDeclaration* decl = new TiXmlDeclaration("1.0","UTF-8","");
	doc.LinkEndChild(decl);

	//block:ProjectParam
	TiXmlElement *root = new TiXmlElement("ProjectParam");
	root->SetAttribute("name", m_Appname.c_str());
	doc.LinkEndChild(root);
	
	//block:DataSource
	TiXmlElement* DataSourceNode = new TiXmlElement("DataSource");
	
	if (m_SourceDataType == CAP_DATA)
		DataSourceNode->SetAttribute("DataType","CAP_DATA");
	else if (m_SourceDataType == MP4_DATA)
		DataSourceNode->SetAttribute("DataType","MP4_DATA");
	else if (m_SourceDataType == YUV_DATA)
		DataSourceNode->SetAttribute("DataType","YUV_DATA");
	root->LinkEndChild(DataSourceNode);
	
	//block:HostSetting
	if (m_SourceDataType == CAP_DATA)
	{
		TiXmlElement* HostSettingsNode = new TiXmlElement("HostSetting");
		if (m_SaveDataType == NONE)
			HostSettingsNode->SetAttribute("SaveDataType","NONE");
		else if (m_SaveDataType == MP4)
			HostSettingsNode->SetAttribute("SaveDataType","MP4");
		else if (m_SaveDataType == YUV)
			HostSettingsNode->SetAttribute("SaveDataType","YUV");
		DataSourceNode->LinkEndChild(HostSettingsNode);

		//block:Host
		list<HostSettings>::iterator iter;
		for (iter=m_HostSettings.begin(); iter != m_HostSettings.end(); iter++)
		{
			const HostSettings& hostSetting=*iter;
			TiXmlElement * host;
			host = new TiXmlElement( "Host" ); 
			HostSettingsNode->LinkEndChild( host ); 
			host->SetAttribute("id", hostSetting.id);
			host->SetAttribute("ipaddr",hostSetting.ipaddr.c_str());
			host->SetAttribute("port", hostSetting.port);
			host->SetAttribute("user",hostSetting.user.c_str());
			host->SetAttribute("passwd",hostSetting.passwd.c_str());
			host->SetAttribute("paramfile",hostSetting.paramfile.c_str());
			host->SetAttribute("savefile",hostSetting.savefile.c_str());
		}
	}	
	

	//block:Mp4Setting
	if(m_SourceDataType == MP4_DATA)
	{
		TiXmlElement* Mp4SettingNode = new TiXmlElement("Mp4Setting");
		DataSourceNode->LinkEndChild(Mp4SettingNode);

		//block:Mp4Path
		list<Mp4Settings>::iterator iter;
		for (iter=m_Mp4Settings.begin(); iter != m_Mp4Settings.end(); iter++)
		{
			const Mp4Settings&  mp4Setting=*iter;
			TiXmlElement * host;
			host = new TiXmlElement( "Mp4Path" ); 
			Mp4SettingNode->LinkEndChild( host ); 
			host->SetAttribute("id", mp4Setting.ChannelId);
			host->SetAttribute("sourcefile",mp4Setting.sourcefile.c_str());
			host->SetAttribute("paramfile", mp4Setting.paramfile.c_str());
		}
	}

	//block:YUVSetting
	if(m_SourceDataType == YUV_DATA)
	{
		TiXmlElement* YUVSettingNode = new TiXmlElement("YUVSetting");
		DataSourceNode->LinkEndChild(YUVSettingNode);

		//block:YUVPath
		list<YUVSettings>::iterator iter;
		for (iter=m_YUVSettings.begin(); iter != m_YUVSettings.end(); iter++)
		{
			const YUVSettings&  yuvSetting=*iter;
			TiXmlElement * host;
			host = new TiXmlElement( "YUVPath" ); 
			YUVSettingNode->LinkEndChild( host ); 
			host->SetAttribute("id", yuvSetting.ChannelId);
			host->SetAttribute("sourcefile",yuvSetting.sourcefile.c_str());
			host->SetAttribute("paramfile", yuvSetting.paramfile.c_str());
		}
	}

	//block:BoxCalibration
	{
		TiXmlElement* BoxCalibrationNode = new TiXmlElement("BoxCalibration");
		root->LinkEndChild(BoxCalibrationNode);
		list<BoxCalibrationSettings>::iterator iter;
		for (iter=m_BoxCalibSetting.begin(); iter != m_BoxCalibSetting.end(); iter++)
		{
			const BoxCalibrationSettings&  boxSetting=*iter;
			TiXmlElement * frontPoint;
			frontPoint = new TiXmlElement( "FrontPoint" ); 
			BoxCalibrationNode->LinkEndChild(frontPoint);
			frontPoint->SetAttribute("id", boxSetting.ChannelId);
			char* buf =(char*)malloc(sizeof(char)*256);
 			sprintf(buf,"%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
				boxSetting.frontPoint[0],boxSetting.frontPoint[1],boxSetting.frontPoint[2],boxSetting.frontPoint[3],
				boxSetting.frontPoint[4],boxSetting.frontPoint[5],boxSetting.frontPoint[6],boxSetting.frontPoint[7],
				boxSetting.backPoint[0],boxSetting.backPoint[1],boxSetting.backPoint[2],boxSetting.backPoint[3],
				boxSetting.backPoint[4],boxSetting.backPoint[5],boxSetting.backPoint[6],boxSetting.backPoint[7]);
			TiXmlText* fText = new TiXmlText(buf);
			frontPoint->LinkEndChild(fText);
			free(buf);
		}
	}

	doc.SaveFile(pFilename); 

}

AppSetting::~AppSetting()
{

}

void loadPoints2()
{
	list<BoxCalibrationSettings>::iterator iter;
	for (iter = appSetting.m_BoxCalibSetting.begin();iter != appSetting.m_BoxCalibSetting.end();iter++)
	{
		BoxCalibrationSettings& boxSetting = *iter;
		int index = boxSetting.ChannelId - 1;
		//__gHostInfo[index].frontPoints = (float*) malloc (sizeof(float)*16);
		__gHostInfo[index].frontPoints = boxSetting.frontPoint;
		__gHostInfo[index].backPoints = boxSetting.backPoint;

	}
}

void loadHostInfo2()
{
	if (appSetting.m_SourceDataType == CAP_DATA)
	{
		list<HostSettings>::iterator iter;
		for (iter=appSetting.m_HostSettings.begin();iter != appSetting.m_HostSettings.end(); iter++)
		{
			const HostSettings& hostSetting=*iter;
			int index = hostSetting.id - 1;
			__gHostInfo[ index ].Port = hostSetting.port;

			strcpy_s( __gHostInfo[ index ].IpAddress, 19, hostSetting.ipaddr.c_str() );
			strcpy_s( __gHostInfo[ index ].UserName, 19,  hostSetting.user.c_str() );
			strcpy_s( __gHostInfo[ index ].Password, 19, hostSetting.passwd.c_str() );
			strcpy_s( __gHostInfo[ index ].File, 19, hostSetting.paramfile.c_str() );
		}
	}else if (appSetting.m_SourceDataType == MP4_DATA)
	{
		list<Mp4Settings>::iterator iter;
		
		for (iter=appSetting.m_Mp4Settings.begin();iter != appSetting.m_Mp4Settings.end();iter++)
		{
			const Mp4Settings& mp4Setting = *iter;
			int index = mp4Setting.ChannelId - 1;
			strcpy_s( __gHostInfo[ index ].File, 19, mp4Setting.paramfile.c_str() );
			strcpy_s( __gHostInfo[ index ].SourceFile, 19, mp4Setting.sourcefile.c_str() );
		}
	}else if (appSetting.m_SourceDataType == YUV_DATA)
	{
		list<YUVSettings>::iterator iter;
		for (iter=appSetting.m_YUVSettings.begin();iter != appSetting.m_YUVSettings.end();iter++)
		{
			const YUVSettings& yuvSetting = *iter;
			int index = yuvSetting.ChannelId - 1;
			strcpy_s( __gHostInfo[ index ].File, 19, yuvSetting.paramfile.c_str() );
			strcpy_s( __gHostInfo[ index ].SourceFile, 30, yuvSetting.sourcefile.c_str() );
		}
	}else
	{
		printf("load project param failed!\n");
	}
}



void loadAppSetting(const char* pFilename)
{
	appSetting.load(pFilename);
	loadHostInfo2();
	loadPoints2();

}

//void saveCalibration(const char* pFilename)
//{
//	TiXmlDocument doc(pFilename);
//	if (!doc.LoadFile()) return;
//
//	TiXmlHandle hDoc(&doc);
//	TiXmlElement* pElem;
//	TiXmlHandle hRoot(0);
//	TiXmlElement* root;
//	pElem = hRoot.FirstChildElement("ProjectParam").FirstChildElement("BoxCalibration").Element();
//	root = hRoot.FirstChildElement("ProjectParam").Element();
//	//block:BoxCalibration
//	{
//		TiXmlElement* BoxCalibrationNode = new TiXmlElement("BoxCalibration");
//		//root->LinkEndChild(BoxCalibrationNode);
//		root->ReplaceChild(pElem,BoxCalibrationNode);
//		list<BoxCalibrationSettings>::iterator iter;
//		for (iter=appSetting.m_BoxCalibSetting.begin(); iter != appSetting.m_BoxCalibSetting.end(); iter++)
//		{
//			const BoxCalibrationSettings&  boxSetting=*iter;
//			TiXmlElement * frontPoint;
//			frontPoint = new TiXmlElement( "FrontPoint" ); 
//			BoxCalibrationNode->LinkEndChild(frontPoint);
//			frontPoint->SetAttribute("id", boxSetting.ChannelId);
//			char* buf =(char*)malloc(sizeof(char)*256);
//			sprintf(buf,"%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
//				boxSetting.frontPoint[0],boxSetting.frontPoint[1],boxSetting.frontPoint[2],boxSetting.frontPoint[3],
//				boxSetting.frontPoint[4],boxSetting.frontPoint[5],boxSetting.frontPoint[6],boxSetting.frontPoint[7],
//				boxSetting.backPoint[0],boxSetting.backPoint[1],boxSetting.backPoint[2],boxSetting.backPoint[3],
//				boxSetting.backPoint[4],boxSetting.backPoint[5],boxSetting.backPoint[6],boxSetting.backPoint[7]);
//			TiXmlText* fText = new TiXmlText(buf);
//			frontPoint->LinkEndChild(fText);
//			free(buf);
//		}
//	}
//	doc.SaveFile(pFilename);
//}

void writePoints()
{
	int j=0;
	FILE* file = fopen("Points.conf","w");

	if( file )
	{
		for( int i = 0; i < 3; i ++ )
		{		

			fprintf( file,"%d %d ", i + 1, 0 );
			for(j=0;j<8;j++)
				fprintf( file," %f ",__gHostInfo[ i ].frontPoints[j]);
			fprintf( file," \r\n");	

			fprintf( file,"%d %d ", i + 1, 1 );
			for(j=0;j<8;j++)
				fprintf( file," %f ",__gHostInfo[ i ].backPoints[j]);
			fprintf( file," \r\n");			
		}

		fclose( file );
	}
}